home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / filesys.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  28KB  |  1,114 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corp.
  4. All rights reserved.
  5. */
  6.  
  7. /*
  8.  * various file system interface things
  9.  */
  10.  
  11. #include "mint.h"
  12.  
  13. #define PATH2COOKIE_DB(x) TRACE(x)
  14.  
  15. FILESYS *active_fs;
  16. FILESYS *drives[NUM_DRIVES];
  17. extern FILESYS tos_filesys;    /* declaration needed for debugging only */
  18.  
  19. /* "aliased" drives are different names
  20.  * for real drives/directories
  21.  * if drive d is an alias for c:\usr,
  22.  * then alias_drv[3] == 2 (the real
  23.  * drive) and aliases has bit (1L << 3)
  24.  * set.
  25.  * NOTE: if aliasdrv[d] is 0, then d is not an aliased drive,
  26.  * otherwise d is aliased to drive aliasdrv[d]-1
  27.  * (e.g. if drive A: is aliased to B:\FOO, then
  28.  * aliasdrv[0] == 'B'-'A'+1 == 2). Always remember to
  29.  * compensate for the extra 1 when dereferencing aliasdrv!
  30.  */
  31. int    aliasdrv[NUM_DRIVES];
  32.  
  33. FILEPTR *flist;        /* a list of free file pointers */
  34.  
  35. char follow_links[1];    /* dummy "name" used as a parameter to path2cookie */
  36.  
  37. /* vector of valid drives, according to GEMDOS */
  38. /* note that this isn't necessarily the same as what the BIOS thinks of
  39.  * as valid
  40.  */
  41. long dosdrvs;
  42.  
  43. /*
  44.  * Initialize a specific drive. This is called whenever a new drive
  45.  * is accessed, or when media change occurs on an old drive.
  46.  * Assumption: at this point, active_fs is a valid pointer
  47.  * to a list of file systems.
  48.  */
  49.  
  50. /* table of processes holding locks on drives */
  51. extern PROC *dlockproc[];    /* in dosdir.c */
  52.  
  53. void
  54. init_drive(i)
  55.     int i;
  56. {
  57.     long r;
  58.     FILESYS *fs;
  59.     fcookie root_dir;
  60.  
  61.     TRACE(("init_drive(%c)", i+'A'));
  62.  
  63.     drives[i] = 0;        /* no file system */
  64.     if (i >= 0 && i < NUM_DRIVES) {
  65.         if (dlockproc[i]) return;
  66.     }
  67.  
  68.     for (fs = active_fs; fs; fs = fs->next) {
  69.         r = (*fs->root)(i, &root_dir);
  70.         if (r == 0) {
  71.             drives[i] = root_dir.fs;
  72.             release_cookie(&root_dir);
  73.             break;
  74.         }
  75.     }
  76. }
  77.  
  78. /*
  79.  * initialize the file system
  80.  */
  81.  
  82. #define NUMFPS    40    /* initial number of file pointers */
  83.  
  84. void
  85. init_filesys()
  86. {
  87.     static FILEPTR initial[NUMFPS+1];
  88.     int i;
  89.     extern FILESYS tos_filesys, bios_filesys, pipe_filesys,
  90.         proc_filesys, uni_filesys;
  91.  
  92. /* get the vector of connected GEMDOS drives */
  93.     dosdrvs = Dsetdrv(Dgetdrv()) | drvmap();
  94.  
  95. /* set up some initial file pointers */
  96.     for (i = 0; i < NUMFPS; i++) {
  97.         initial[i].devinfo = (ulong) (&initial[i+1]);
  98.     }
  99.     initial[NUMFPS].devinfo = 0;
  100.     flist = initial;
  101.  
  102. /* set up the file systems */
  103.     tos_filesys.next = 0;
  104.     bios_filesys.next = &tos_filesys;
  105.     pipe_filesys.next = &bios_filesys;
  106.     proc_filesys.next = &pipe_filesys;
  107.     uni_filesys.next = &proc_filesys;
  108.  
  109.     active_fs = &uni_filesys;
  110.  
  111. /* initialize the BIOS file system */
  112.     biosfs_init();
  113.  
  114. /* initialize the unified file system */
  115.     unifs_init();
  116. }
  117.  
  118. /*
  119.  * load file systems from disk
  120.  * this routine is called after process 0 is set up, but before any user
  121.  * processes are run
  122.  *
  123.  * NOTE that a number of directory changes take place here: we look first
  124.  * in the current directory, then in the directory \mint, and finally
  125.  * the d_lock() calls force us into the root directory.
  126.  */
  127.  
  128. typedef FILESYS * ARGS_ON_STACK (*FSFUNC) P_((struct kerinfo *));
  129.  
  130. void
  131. load_filesys()
  132. {
  133.     long r;
  134.     BASEPAGE *b;
  135.     FILESYS *fs;
  136.     FSFUNC initf;
  137.     static DTABUF dta;
  138.     int i;
  139.     extern struct kerinfo kernelinfo; /* in main.c */
  140.     char curpath[PATH_MAX];
  141.     MEMREGION *xfsreg;
  142. #define NPATHS 3
  143.     static const char *paths[NPATHS] = {"", "\\MINT", "\\MULTITOS"};
  144.  
  145.     curproc->dta = &dta;
  146.     d_getpath(curpath,0);
  147.  
  148.     for (i = 0; i < NPATHS; i++) {
  149.         if (*paths[i]) {
  150. /* don't bother checking the current directory twice! */
  151.             if (!stricmp(paths[i],curpath))
  152.             r = -1;
  153.             else
  154.             r = d_setpath(paths[i]);
  155.         }
  156.         else
  157.             r = 0;
  158.  
  159.         if (r == 0)
  160.             r = f_sfirst("*.xfs", 0);
  161.  
  162.         while (r == 0) {
  163.         b = (BASEPAGE *)p_exec(3, dta.dta_name, (char *)"", (char *)0);
  164.         if ( ((long)b) < 0 ) {
  165.             DEBUG(("Error loading file system %s", dta.dta_name));
  166.             r = f_snext();
  167.             continue;
  168.         }
  169.     /* we leave a little bit of slop at the end of the loaded stuff */
  170.         m_shrink(0, (virtaddr)b, 512 + b->p_tlen + b->p_dlen + b->p_blen);
  171.         initf = (FSFUNC)b->p_tbase;
  172.         TRACE(("initializing %s", dta.dta_name));
  173.         fs = (*initf)(&kernelinfo);
  174.  
  175.         if (fs) {
  176.             TRACE(("%s loaded OK", dta.dta_name));
  177.     /* put the loaded XFS into super accesible memory */
  178.             xfsreg = addr2region( (long) b );
  179.             mark_region(xfsreg, PROT_S);
  180.     /* link it into the list of drivers */
  181.             fs->next = active_fs;
  182.             active_fs = fs;
  183.         } else {
  184.             DEBUG(("%s returned null", dta.dta_name));
  185.             m_free((virtaddr)b);
  186.         }
  187.         r = f_snext();
  188.         }
  189.     }
  190.  
  191. /* here, we invalidate all old drives EXCEPT for ones we're already using (at
  192.  * this point, only the bios devices should be open)
  193.  * this gives newly loaded file systems a chance to replace the
  194.  * default tosfs.c
  195.  */
  196.     for (i = 0; i < NUM_DRIVES; i++) {
  197.         if (d_lock(1, i) == 0)    /* lock if possible */
  198.             d_lock(0, i);    /* and then unlock */
  199.     }
  200. }
  201.  
  202. void
  203. close_filesys()
  204. {
  205.     PROC *p;
  206.     FILEPTR *f;
  207.     int i;
  208.  
  209.     TRACE(("close_filesys"));
  210. /* close every open file */
  211.     for (p = proclist; p; p = p->gl_next) {
  212.         for (i = MIN_HANDLE; i < MAX_OPEN; i++) {
  213.             if ( (f = p->handle[i]) != 0) {
  214.                 if (p->wait_q == TSR_Q || p->wait_q == ZOMBIE_Q)
  215.                     ALERT("Open file for dead process?");
  216.                 do_pclose(p, f);
  217.             }
  218.         }
  219.     }
  220. }
  221.  
  222. /*
  223.  * "media change" routine: called when a media change is detected on device
  224.  * d, which may or may not be a BIOS device. All handles associated with
  225.  * the device are closed, and all directories invalidated. This routine
  226.  * does all the dirty work, and is called automatically when
  227.  * disk_changed detects a media change.
  228.  */
  229.  
  230. void ARGS_ON_STACK 
  231. changedrv(d)
  232.     unsigned d;
  233. {
  234.     PROC *p;
  235.     int i;
  236.     FILEPTR *f;
  237.     FILESYS *fs;
  238.     SHTEXT *stext;
  239.     extern SHTEXT *text_reg;    /* in mem.c */
  240.     DIR *dirh;
  241.     fcookie dir;
  242.     int warned = (d & 0xf000) == PROC_BASE_DEV;
  243.     long r;
  244.  
  245. /* if an aliased drive, change the *real* device */
  246.     if (d < NUM_DRIVES && aliasdrv[d]) {
  247.         d = aliasdrv[d] - 1;    /* see NOTE above */
  248.     }
  249.  
  250. /* re-initialize the device, if it was a BIOS device */
  251.     if (d < NUM_DRIVES) {
  252.         fs = drives[d];
  253.         if (fs) {
  254.             (void)(*fs->dskchng)(d);
  255.         }
  256.         init_drive(d);
  257.     }
  258.  
  259.     for (p = proclist; p; p = p->gl_next) {
  260.     /* invalidate all open files on this device */
  261.         for (i = MIN_HANDLE; i < MAX_OPEN; i++) {
  262.             if (((f = p->handle[i]) != 0) && (f->fc.dev == d)) {
  263.                 if (!warned) {
  264.                 ALERT(
  265. "Files were open on a changed drive (0x%x)!", d);
  266.                 warned++;
  267.                 }
  268.  
  269. /* we set f->dev to NULL to indicate to do_pclose that this is an
  270.  * emergency close, and that it shouldn't try to make any
  271.  * calls to the device driver since the file has gone away
  272.  */
  273.                 f->dev = NULL;
  274.                 (void)do_pclose(p, f);
  275. /* we could just zero the handle, but this could lead to confusion if
  276.  * a process doesn't realize that there's been a media change, Fopens
  277.  * a new file, and gets the same handle back. So, we force the
  278.  * handle to point to /dev/null.
  279.  */
  280.                 p->handle[i] =
  281.                 do_open("U:\\DEV\\NULL", O_RDWR, 0, (XATTR *)0);
  282.             }
  283.         }
  284.  
  285.     /* terminate any active directory searches on the drive */
  286.     /* BUG: This handles only Fsfirst/Fsnext searches! */
  287.         for (i = 0; i < NUM_SEARCH; i++) {
  288.             dirh = &p->srchdir[i];
  289.             if (dirh->fc.fs && dirh->fc.dev == d) {
  290.                 TRACE(("closing search for process %d", p->pid));
  291.                 release_cookie(&dirh->fc);
  292.                 dirh->fc.fs = 0;
  293.                 p->srchdta[i] = 0;
  294.             }
  295.         }
  296.  
  297.         if (d >= NUM_DRIVES) continue;
  298.  
  299.     /* change any active directories on the device to the (new) root */
  300.         fs = drives[d];
  301.         if (fs) {
  302.             r = (*fs->root)(d, &dir);
  303.             if (r != E_OK) dir.fs = 0;
  304.         } else {
  305.             dir.fs = 0; dir.dev = d;
  306.         }
  307.  
  308.         for (i = 0; i < NUM_DRIVES; i++) {
  309.             if (p->root[i].dev == d) {
  310.                 release_cookie(&p->root[i]);
  311.                 dup_cookie(&p->root[i], &dir);
  312.             }
  313.             if (p->curdir[i].dev == d) {
  314.                 release_cookie(&p->curdir[i]);
  315.                 dup_cookie(&p->curdir[i], &dir);
  316.             }
  317.         }
  318.         release_cookie(&dir);
  319.     }
  320.  
  321. /* free any file descriptors associated with shared text regions */
  322.     for (stext = t